import TreeSelectTitleRender from '@/components/TreeSelectTitleRender';
import type { PermissionRecord } from '@/DatabaseType/Permission';
import {
  addPermission,
  deletePermission,
  getPermissionTree,
  updatePermission,
} from '@/services/permission';
import { DEFAULT_REQUIRED_RULE, MODAL_TITLE_MAP } from '@/constant';
import type { MergeDataNode } from '@/utils/permissionTree';
import { formatPermissionTreeToTreeFC } from '@/utils/permissionTree';
import { ResponseCode } from '@/utils/request';
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
import { PageContainer } from '@ant-design/pro-components';
import {
  Button,
  Card,
  Col,
  Form,
  Input,
  message,
  Modal,
  notification,
  Popconfirm,
  Radio,
  Row,
  Select,
  Space,
  Tree,
} from 'antd';
import copy from 'copy-to-clipboard';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { FormLayout, ROOT_PERMISSION_RECORD } from '../Common/config';
import StyleModule from './style.module.less';

const InitFormData = () => ({
  // 默认是菜单类型
  funcType: '1',
  // 默认从根节点创建
  parentId: 0,
  type: 1,
  pageUrl: '',
  apiList: [],
  name: '',
  znName: '',
});

const RoleManagement = () => {
  const [modalConfig, setModalConfig] = useState<{
    visible: boolean;
    type: 'edit' | 'view' | 'add';
    permission?: PermissionRecord;
  }>({
    visible: false,
    type: 'edit',
  });
  // 弹窗表单实例
  const [formInstance] = Form.useForm();
  const [operateLoading, setOperateLoadingLoading] = useState(false);

  // 选中的权限节点
  const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
  // 展开的权限节点
  const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
  // 权限树options数据
  const [treeData, setTreeData] = useState<MergeDataNode[]>([]);
  // 权限树铺平数据，为了方便选择父节点创建权限
  const [permissionList, setPermissionList] = useState<PermissionRecord[]>([]);
  // 权限树加载loading
  const [loading, setLoading] = useState(true);
  const [initFlag, setInitFlag] = useState(false);

  // 菜单权限列表
  const menuPermissionOptions = useMemo(() => {
    return permissionList
      .filter((item) => item.funcType === '1')
      .map((item) => ({
        ...item,
        value: item.id,
        label: `${item.znName}(${item.name})`,
      }));
  }, [permissionList]);

  // 去创建权限
  const toAddPermission = useCallback(
    (parentId?: number, funcType?: PermissionRecord['funcType']) => {
      const formData = InitFormData();
      if (parentId) {
        formData.parentId = parentId;
      }
      if (funcType) {
        formData.funcType = funcType;
      }
      setModalConfig((config) => ({ ...config, visible: true, type: 'add' }));
      formInstance.setFieldsValue(formData);
    },
    [formInstance],
  );

  // 删除权限动作
  const sureDeletePermission = useCallback(async (permissionId: number) => {
    try {
      const { code, message: msg } = await deletePermission(permissionId);
      if (code === ResponseCode.Success) {
        notification.success({ message: '删除权限成功' });
        // 清除当前的选中效果
        setSelectedKeys([]);
        // 重新拉取数据
        setInitFlag((flag) => !flag);
      } else {
        notification.error({ message: msg || '删除权限失败' });
      }
    } catch (error: any) {
      notification.error({ message: error?.message || '删除权限失败' });
    }
  }, []);

  // 权限树如何渲染title
  const titleRender = useCallback(
    (node: MergeDataNode) => {
      const { funcType, idPath } = node;
      const idPaths = idPath.split('/');
      let parentId: string | number = idPaths[idPaths.length - 1];
      // 如果为空串，父节点是 0
      parentId = Number(parentId ? parentId : 0);
      let selected = false;
      if (selectedKeys.includes(node.id)) selected = true;
      return (
        <TreeSelectTitleRender
          node={node}
          // 额外渲染的内容
          extraElement={
            selected && (
              <Space
                className="operation"
                style={{ marginLeft: 8 }}
                // 阻止冒泡和默认行为
                onClick={(event) => {
                  event.preventDefault();
                  event.stopPropagation();
                }}
              >
                <a
                  key="edit"
                  onClick={() => {
                    setModalConfig((config) => ({
                      ...config,
                      visible: true,
                      type: 'edit',
                      permission: node,
                    }));
                    formInstance.setFieldsValue({
                      ...node,
                      parentId,
                    });
                  }}
                >
                  编辑
                </a>
                <Popconfirm
                  key="delete"
                  title="确认删除该记录吗？"
                  okText="是"
                  cancelText="否"
                  onConfirm={() => sureDeletePermission(node.id)}
                >
                  <a href="#">删除</a>
                </Popconfirm>
                <a
                  key="copy"
                  onClick={() => {
                    copy(JSON.stringify(node));
                    message.success('复制配置成功');
                  }}
                >
                  复制
                </a>
                {/* 只有菜单节点才能新增子节点 start */}
                {funcType === '1' && [
                  <a
                    key="add-menu"
                    onClick={() => toAddPermission(node.id, '1')}
                  >
                    新增菜单
                  </a>,
                  <a
                    key="add-button"
                    onClick={() => toAddPermission(node.id, '2')}
                  >
                    新增按钮
                  </a>,
                ]}
                {/* 只有菜单节点才能新增子节点 end */}
              </Space>
            )
          }
        />
      );
    },
    [formInstance, selectedKeys, sureDeletePermission, toAddPermission],
  );

  // 初始化获取数据
  useEffect(() => {
    setLoading(true);
    getPermissionTree()
      .then(({ data, code, message: msg }) => {
        if (code === ResponseCode.Success) {
          const { permissionTree, permissionList: list } = data;
          // 设置权限树options
          setTreeData(formatPermissionTreeToTreeFC(permissionTree));
          // 设置权限铺平列表
          setPermissionList([...list, ROOT_PERMISSION_RECORD]);
          // 默认展开一级菜单
          setExpandedKeys(permissionTree.map((item) => item.id));
        } else {
          message.error(msg);
        }
      })
      .catch(() => {
        console.log('RoleManagement => index => getPermissionTree', '请求失败');
      })
      .finally(() => {
        setLoading(false);
      });
    // 设置初始化控制参数，如果initFlag变化，重新初始化数据
  }, [initFlag]);

  // 确定提交
  async function sureAddPermission() {
    switch (modalConfig.type) {
      case 'add': {
        const formData = await formInstance.validateFields();
        setOperateLoadingLoading(true);
        try {
          const {
            data: newPermissionId,
            code,
            message: msg,
          } = await addPermission({
            ...formData,
            apiList: JSON.stringify(formData.apiList || '[]'),
          });
          if (code === ResponseCode.Success) {
            setModalConfig((config) => ({ ...config, visible: false }));
            setInitFlag((flag) => !flag);
            notification.success({
              message: `新增权限ID: ${newPermissionId}成功`,
            });
          } else {
            notification.error({ message: msg || '新增权限失败' });
          }
        } catch (error: any) {
          notification.error({ message: error?.message || '新增权限失败' });
        }
        setOperateLoadingLoading(false);
        break;
      }
      case 'edit': {
        const formData = await formInstance.validateFields();
        setOperateLoadingLoading(true);
        try {
          const { code, message: msg } = await updatePermission(
            modalConfig.permission?.id as number,
            formData,
          );
          if (code === ResponseCode.Success) {
            setModalConfig((config) => ({ ...config, visible: false }));
            setInitFlag((flag) => !flag);
            notification.success({ message: `更新权限成功` });
          } else {
            notification.error({ message: msg || '更新权限失败' });
          }
        } catch (error: any) {
          notification.error({ message: error?.message || '更新权限失败' });
        }
        setOperateLoadingLoading(false);
        break;
      }
      case 'view': {
        throw new Error('Not implemented yet: "view" case');
      }
    }
  }

  return (
    <PageContainer className={StyleModule['permission-management']}>
      <Card loading={loading}>
        {/* 操作台 start */}
        <div className="operation-top">
          <Space>
            <Button type="primary" onClick={() => toAddPermission()}>
              <PlusOutlined />
              新增权限
            </Button>
          </Space>
        </div>
        {/* 操作台 end */}

        {/* 权限树渲染 start */}
        <Tree<MergeDataNode>
          checkable={false}
          treeData={treeData}
          showLine={{ showLeafIcon: false }}
          fieldNames={{
            title: 'znName',
            key: 'id',
            children: 'children',
          }}
          titleRender={titleRender}
          selectedKeys={selectedKeys}
          expandedKeys={expandedKeys}
          onSelect={setSelectedKeys}
          onExpand={setExpandedKeys}
        />
        {/* 权限树渲染 end */}
      </Card>

      {/* 新增/编辑权限弹窗 start */}
      <Modal
        title={
          <Space className="modal-title">
            <span>{MODAL_TITLE_MAP[modalConfig.type]}</span>
            <a
              onClick={() => {
                copy(JSON.stringify(formInstance.getFieldsValue()));
                message.success('复制配置成功');
              }}
            >
              复制到剪贴板
            </a>
          </Space>
        }
        open={modalConfig.visible}
        onCancel={() =>
          setModalConfig((config) => ({
            ...config,
            visible: false,
            permission: undefined,
          }))
        }
        centered
        className={StyleModule['permission-management-modal']}
        onOk={sureAddPermission}
        confirmLoading={operateLoading}
      >
        <Form
          {...FormLayout}
          form={formInstance}
          disabled={modalConfig.type === 'view'}
          initialValues={InitFormData()}
          tabIndex={0}
          onPaste={(event) => {
            const copyText = event.clipboardData.getData('text');
            console.log(copyText);
            try {
              formInstance.setFieldsValue(JSON.parse(copyText));
            } catch (error) {
              console.log(copyText, '解析异常');
            }
          }}
        >
          <Form.Item
            label="父节点"
            name="parentId"
            rules={DEFAULT_REQUIRED_RULE}
          >
            <Select options={menuPermissionOptions} />
          </Form.Item>
          <Form.Item
            label="功能类型"
            name="funcType"
            rules={DEFAULT_REQUIRED_RULE}
          >
            <Radio.Group
              options={[
                {
                  label: '菜单',
                  value: '1',
                },
                {
                  label: '按钮',
                  value: '2',
                },
              ]}
              optionType="button"
              buttonStyle="solid"
              // 编辑的时候不允许修改菜单类型
              disabled={modalConfig.type === 'edit'}
            />
          </Form.Item>
          <Form.Item
            noStyle
            shouldUpdate={(prev, curr) => prev?.funcType !== curr?.funcType}
          >
            {({ getFieldValue }) => {
              const funcType = getFieldValue(
                'funcType',
              ) as PermissionRecord['funcType'];
              if (funcType === '1') {
                return (
                  <Form.Item
                    label="页面URL"
                    name="pageUrl"
                    rules={DEFAULT_REQUIRED_RULE}
                  >
                    <Input />
                  </Form.Item>
                );
              }
              return null;
            }}
          </Form.Item>
          <Form.Item
            name="name"
            label="权限英文名"
            rules={DEFAULT_REQUIRED_RULE}
          >
            <Input />
          </Form.Item>
          <Form.Item
            name="znName"
            label="权限中文名"
            rules={DEFAULT_REQUIRED_RULE}
          >
            <Input />
          </Form.Item>
          <Form.Item label="接口鉴权" extra="请求方式 + 空格 + 接口路径">
            <Form.List name="apiList">
              {(fields, { add, remove }) => {
                return (
                  <div className="api-list-container">
                    {fields.map((field) => (
                      <Form.Item key={field.name}>
                        <Row>
                          <Col flex={'1 1 0'}>
                            <Form.Item
                              noStyle
                              name={field.name}
                              rules={DEFAULT_REQUIRED_RULE}
                            >
                              <Input />
                            </Form.Item>
                          </Col>
                          <Col>
                            <Button
                              onClick={() => remove(field.name)}
                              className="delete-api-button"
                            >
                              <MinusCircleOutlined /> 删除
                            </Button>
                          </Col>
                        </Row>
                      </Form.Item>
                    ))}
                    <Button onClick={() => add('')} className="add-api-button">
                      <PlusOutlined /> 添加接口
                    </Button>
                  </div>
                );
              }}
            </Form.List>
          </Form.Item>
        </Form>
      </Modal>
      {/* 新增/编辑权限弹窗 end */}
    </PageContainer>
  );
};

export default RoleManagement;
